package main

import (
	"time"
	"github.com/gomodule/redigo/redis"
	"fmt"
	"github.com/json-iterator/go"
	"strconv"
)

type Order struct {
	Id int64
	OrderTime time.Time
	Signed bool
	SigningTime time.Time
	BillingTime string
	CommodityList []*OrderCommodity
}

// type OrderCommodity struct {
//   Id int64
//   OrderId int64
//   CommodityId int64
//   Number int
// }

type OrderCommodity struct {
	Commodity *Commodity
	Number int
}

type Commodity struct {
	Id int64
	Name string
	ServiceCycle int
}

func InsertSort(list *[]*OrderCommodity) {
	n := len(*list)
	// 进行 N-1 轮迭代
	for i := 1; i <= n-1; i++ {
		deal := (*list)[i] // 待排序的数
		j := i - 1      // 待排序的数左边的第一个数的位置

		// 如果第一次比较，比左边的已排好序的第一个数小，那么进入处理
		if deal.Commodity.ServiceCycle < (*list)[j].Commodity.ServiceCycle {
			// 一直往左边找，比待排序大的数都往后挪，腾空位给待排序插入
			for ; j >= 0 && deal.Commodity.ServiceCycle < (*list)[j].Commodity.ServiceCycle; j-- {
				(*list)[j+1] = (*list)[j] // 某数后移，给待排序留空位
			}
			(*list)[j+1] = deal // 结束了，待排序的数插入空位
		}
	}
}

func GetInvoiceableTime(orderId string, poolConn redis.Conn) Order{
	var o Order
	res, err := poolConn.Do("Get", "order_"+orderId)
	if res == nil ||err != nil{
		fmt.Println("err：", err)
	}

	jerr := jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(res.([]byte), &o)
	if jerr != nil{
		fmt.Println("jerr：", jerr)
	}

	InsertSort(&o.CommodityList)
	fmt.Println("o.CommodityList：", o.CommodityList)
	serviceDay := o.CommodityList[len(o.CommodityList)-1].Commodity.ServiceCycle
	if o.Signed == true{

		currentYear, currentMonth, _ := o.SigningTime.Date()
		currentLocation := o.SigningTime.Location()
		firstOfMonth := time.Date(currentYear, currentMonth, 1, 0, 0, 0, 0, currentLocation)
		lastOfMonth := firstOfMonth.AddDate(0, 1, -1)
		fmt.Println("lastOfMonth：", lastOfMonth)

		billingStartTime := o.SigningTime.AddDate(0, 0, serviceDay)
		fmt.Println("billingStartTime：", billingStartTime)

		loadLocation, _ := time.LoadLocation("Asia/Shanghai")
		monthEndTime, _ := time.ParseInLocation("2006-01-02 15:04:05", lastOfMonth.Format("2006-01-02")+" "+" 23:59:59", loadLocation)
		fmt.Println("monthEndTime：", monthEndTime)

		billingEndTime := billingStartTime.AddDate(0, 0, 7)
		fmt.Println("billingEndTime：", billingEndTime)

		if billingStartTime.Before(monthEndTime) == true && billingEndTime.After(monthEndTime) == true{
			o.BillingTime = billingStartTime.Format("2006-01-02 15:04:05") + " 至 " + monthEndTime.Format("2006-01-02 15:04:05")
		}else {
			o.BillingTime = billingStartTime.Format("2006-01-02 15:04:05") + " 至 " + billingEndTime.Format("2006-01-02 15:04:05")
		}

	}else {
		o.BillingTime = "签收后的" + strconv.Itoa(serviceDay) +"天至" + strconv.Itoa(serviceDay+7) + "天"
	}

	return o
}

func main(){
	pool := &redis.Pool{
		MaxIdle : 10,
		MaxActive : 0,
		IdleTimeout : 100,
		Dial : func()(redis.Conn, error){
			return redis.Dial("tcp", "127.0.0.1:6379")
		},
	}
	poolConn := pool.Get()

	var order = Order{
		Id : 1234543213345456,
		OrderTime :time.Now(),
		Signed : true,
		SigningTime : time.Now().AddDate(0, 0, 8),
		CommodityList :[]*OrderCommodity{
			&OrderCommodity{
				Commodity :&Commodity{
					Id :1435345346345,
					Name :"奇异果",
					ServiceCycle : 10,
				},
				Number:3,
			},
			&OrderCommodity{
				Commodity :&Commodity{
					Id :1435345346346,
					Name :"坚果",
					ServiceCycle : 9,
				},
				Number : 2,
			},
			&OrderCommodity{
				Commodity :&Commodity{
					Id :1435345346347,
					Name :"花生",
					ServiceCycle : 8,
				},
				Number : 1,
			},
			&OrderCommodity{
				Commodity :&Commodity{
					Id :1435345346348,
					Name :"人生果",
					ServiceCycle : 7,
				},
				Number : 4,
			},
			&OrderCommodity{
				Commodity :&Commodity{
					Id :1435345346349,
					Name :"火龙果",
					ServiceCycle : 6,
				},
				Number : 6,
			},
		},
	}
	res, jerr:= jsoniter.ConfigCompatibleWithStandardLibrary.Marshal(&order)
	if jerr != nil{
		fmt.Println(jerr)
	}
	_, dErr := poolConn.Do("Set", "order_"+strconv.FormatInt(order.Id,10), string(res), "ex", 3600)
	if dErr != nil{
		fmt.Println(dErr)
	}

	fmt.Println(GetInvoiceableTime("1234543213345456", poolConn).BillingTime)
}
